
from datetime import datetime
import json
import requests
from xtquant import xtdata
from constants.recognition import TimeStrategy
from constants.trading_session import TradingSession
from recognition.context import RecognitionContext, RecognitionInstance


def generate_extend_tick(tick):
    lastPrice=tick.get("lastPrice")
    lastClose=tick.get("lastClose")
    time=tick.get("time")
    high = tick.get("high")
    low = tick.get("low")
    
    try:
        lastPrice=float(lastPrice)
    except (ValueError, TypeError):
        lastPrice=0
    if lastClose != 0: 
        chg=((lastPrice - lastClose) / lastClose) * 100
        chg = round(chg, 2)
    else:
        chg=0
    if lastClose != 0:
        amplitude = ((high - low) / lastClose) * 100
        amplitude = round(amplitude, 2)
    else:
        amplitude = 0
    
    extend_tick ={**tick,"chg":chg,"amplitude":amplitude,"current_time":datetime.fromtimestamp(time//1000).strftime("%Y-%m-%d %H:%M:%S"),"lastPrice":lastPrice}

    return extend_tick

class Stock:
    __call_auction_is_trigger=False
    __late_trading_is_trigger=False
    __close=False
    
    def __init__(self,code,strageties=[]):
       info = xtdata.get_instrument_detail(code)
       self.info=info
       self.code=code
       self.triggerRecord={}
       klines=xtdata.get_market_data_ex(field_list=[],stock_list=[code],period="1d",count=30,dividend_type='none', fill_data=True)
    #    last_tick=xtdata.get_market_data_ex(field_list=[],stock_list=[code],period="tick",count=6,dividend_type='none', fill_data=True)
    #    print("-----------------")
    #    print(last_tick)
       self.klines=klines[code]
       self.reconition_context=RecognitionContext()
       for strategy in strageties:
           if strategy in RecognitionInstance:
               self.reconition_context.register(RecognitionInstance[strategy]())
    
    def trigger(self,tick):
       
        # xtdata.download_history_data(self.code,period="tick",end_time=datetime.now().replace(hour=15, minute=0, second=0, microsecond=0).strftime("%Y%m%d%H%M%S"),incrementally=True)
        df = datetime.fromtimestamp(tick["time"]//1000)
        extend_tick=generate_extend_tick(tick)
        if df.time()>=TradingSession.CALL_AUCTION_TIME.value and df.time() < TradingSession.MORNING_START_TIME.value and self.__call_auction_is_trigger==False:
            self.__call_auction_is_trigger=True
			# 触发集合竞价
            self.call_auction(extend_tick)
        if df.time()>=TradingSession.MORNING_START_TIME.value and df.time()<=TradingSession.MORNING_END_TIME.value:
			# 触发早盘
            self.trading(extend_tick)
        if df.time()>=TradingSession.MIDDAY_START_TIME.value and df.time()<=TradingSession.MIDDAY_END_TIME.value:
			# 触发午盘
            self.trading(extend_tick)
        if df.time()>=TradingSession.CLOSE_ORDER_TIME.value and self.__late_trading_is_trigger==False:
            self.__late_trading_is_trigger=True
			# 触发尾盘
            self.late_trading(extend_tick)
        if df.time()>=TradingSession.CLOSE_TIME.value and self.__close==False:
            self.__close=True
            self.close(extend_tick)
    
    def call_auction(self,tick):
        instances=self.reconition_context.get(TimeStrategy.CALL_AUCTION.value)
        if instances==None: return
        for type in instances:
            if type in self.triggerRecord:
                continue
            inst=instances[type]
            if inst.recognize({'tick':tick,"info":self.info,"code":self.code,"stock_instance":self}):
                self.generateTriggerRecord(inst.type,tick)

    def trading(self,tick):
        instances=self.reconition_context.get(TimeStrategy.TRADING.value)
        if instances==None: return
        for type in instances:
            if type in self.triggerRecord:
                continue
            inst=instances[type]
            if inst.recognize({'tick':tick,"info":self.info,"code":self.code,"klines":self.klines,"stock_instance":self}):
                self.generateTriggerRecord(inst.type,tick)

    def late_trading(self,tick):
        pass

    def close(self,tick):
        self.pushTriggerRecord()
        xtdata.download_history_data(self.code,period="1d",start_time="20050101",incrementally=True)

    def generateTriggerRecord(self,type,tick):
        
        self.triggerRecord[type]={
            "triggerPrice":tick.get("lastPrice"),
            "triggerChg":tick.get("chg"),
            "triggerTime":tick.get("time"),
            "recognitionStrategy": type,
        }
        try:
             requests.post('http://192.168.4.2:6666/trigger-records/push',json={"name":self.info["InstrumentName"],"code":self.info["UniCode"],"market":self.info["ExchangeID"].lower(),"triggeredTypes":list(self.triggerRecord.keys())})
        except:
            print(f"触发记录推送失败：{json.dumps(self.triggerRecord[type])}")
    
    def pushTriggerRecord(self):
        triggers=[]
        for type in self.triggerRecord:
            triggers.append({**self.triggerRecord[type],})
        try:
            if len(triggers)==0: return
            requests.post('http://192.168.4.2:6666/triggerRecord',json={"code":self.info["UniCode"],"triggers":triggers})
        except:
            print(f"推送触发日志：{json.dumps(self.triggerRecord[type])}")


         

